package com.chatroom.client.ui;

import com.chatroom.client.Client;
import com.chatroom.client.model.ChatMessage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.html.HTMLDocument;
import java.awt.*;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.net.URL;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 【最终优化版】负责渲染聊天气泡的面板。
 * 核心优化:
 * 1. 通过CSS width属性强制JTextPane内容在指定宽度内换行，解决长文本不换行和横向滚动条问题。
 * 2. 确认了头像和箭头的顶部对齐逻辑是正确的。
 */
public class BubblePanel extends JPanel {

    // --- 常量 ---
    private static final int AVATAR_SIZE = 40;
    private static final int ARROW_WIDTH = 8;
    private static final int ARROW_HEIGHT = 12;
    private static final int ARROW_TOP_OFFSET = 15; // 箭头距离顶部的偏移, 这个值确保了箭头指向头像的上半部分
    private static final int BUBBLE_RADIUS = 20;
    private static final Pattern EMOJI_PATTERN = Pattern.compile("\\[([a-zA-Z0-9_]+?)\\]");

    // --- 成员变量 ---
    private final ChatMessage message;
    private final Map<String, ImageIcon> emojiCache;

    public BubblePanel(ChatMessage message, int listWidth, Map<String, ImageIcon> emojiCache) {
        super(new BorderLayout());
        this.message = message;
        this.emojiCache = emojiCache;
        setOpaque(false);

        // 创建文本面板
        JEditorPane textPane = new JEditorPane();
        textPane.setEditorKit(JEditorPane.createEditorKitForContentType("text/html"));
        // [MODIFIED] 关键改动在此处！
        // -------------------------------------------------------------------------
        // 关键步骤：为HTML文档设置一个“基准URL”。
        // 这告诉JEditorPane在哪里查找像 <img src='smile.png'> 这样的相对路径资源。
        HTMLDocument doc = (HTMLDocument) textPane.getDocument();
        URL baseUrl = Client.class.getResource("/emojis/"); // 使用一个稳定的类来获取资源
        if (baseUrl != null) {
            doc.setBase(baseUrl);
        } else {
            // 这是一个严重错误，必须在控制台打印出来，因为它会导致所有表情都无法显示
            System.err.println("严重错误: 无法找到表情资源文件夹 '/emojis/'！");
        }
        textPane.setEditable(false);
        textPane.setOpaque(false);
        textPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);

        // 设置边距，考虑箭头的位置
        int leftPadding = message.isMine() ? 12 : 12 + ARROW_WIDTH;
        int rightPadding = message.isMine() ? 12 + ARROW_WIDTH : 12;
        textPane.setBorder(new EmptyBorder(8, leftPadding, 8, rightPadding));

        // 处理文本内容
        String textColor = message.isMine() ? "white" : "black";
        String content = message.getContent()
                .replace("&", "&amp;")
                .replace("<", "&lt;")
                .replace(">", "&gt;")
                .replace("\n", "<br>");

        // 处理表情符号
        Matcher matcher = EMOJI_PATTERN.matcher(content);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String emojiCode = matcher.group(0);
            if (this.emojiCache.containsKey(emojiCode)) {
                String emojiName = emojiCode.substring(1, emojiCode.length() - 1);
                // 新代码:
                String imgTag = String.format("<img src='%s.png' width='24' height='24' style='vertical-align: middle;'>", emojiName);

                matcher.appendReplacement(sb, Matcher.quoteReplacement(imgTag));
            } else {
                matcher.appendReplacement(sb, emojiCode);
            }
        }
        matcher.appendTail(sb);
        content = sb.toString();

// 计算最大宽度（考虑头像和间距）
        int maxWidth = (int) (listWidth * 0.7) - AVATAR_SIZE - 40;

        // 使用更灵活的 HTML 样式，设置 display:inline-block 使容器能自适应内容高度
        String html = String.format(
                "<html><div style='display:inline-block; font-family:微软雅黑; font-size:16pt; color:%s; " +
                        "padding:0; margin:0; line-height:24px; white-space:pre-wrap; word-wrap:break-word; " +
                        "max-width:%dpx;'>%s</div></html>",
                textColor, maxWidth - leftPadding - rightPadding, content
        );
        textPane.setText(html);

        // 计算实际内容大小
        textPane.setSize(maxWidth, Short.MAX_VALUE);
        int preferredHeight = textPane.getPreferredSize().height;

        // 获取实际文本宽度
        int actualWidth = Math.min(textPane.getPreferredSize().width, maxWidth);
        actualWidth = Math.max(actualWidth, 80); // 设置最小宽度

        // 设置面板大小
        Dimension size = new Dimension(actualWidth + ARROW_WIDTH, preferredHeight);
        setPreferredSize(size);
        setMaximumSize(new Dimension(maxWidth + ARROW_WIDTH, preferredHeight));

        // 直接添加文本面板，不使用滚动面板
        add(textPane, BorderLayout.CENTER);
    }

    @Override
    protected void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(message.isMine() ? new Color(0, 153, 255) : Color.WHITE);
        int w = getWidth();
        int h = getHeight();
        Area bubbleArea = message.isMine()
                ? new Area(new RoundRectangle2D.Double(0, 0, w - ARROW_WIDTH, h, BUBBLE_RADIUS, BUBBLE_RADIUS))
                : new Area(new RoundRectangle2D.Double(ARROW_WIDTH, 0, w - ARROW_WIDTH, h, BUBBLE_RADIUS, BUBBLE_RADIUS));
        Polygon arrowPolygon = new Polygon();
        if (message.isMine()) {
            arrowPolygon.addPoint(w - ARROW_WIDTH, ARROW_TOP_OFFSET);
            arrowPolygon.addPoint(w, ARROW_TOP_OFFSET + ARROW_HEIGHT / 2);
            arrowPolygon.addPoint(w - ARROW_WIDTH, ARROW_TOP_OFFSET + ARROW_HEIGHT);
        } else {
            arrowPolygon.addPoint(ARROW_WIDTH, ARROW_TOP_OFFSET);
            arrowPolygon.addPoint(0, ARROW_TOP_OFFSET + ARROW_HEIGHT / 2);
            arrowPolygon.addPoint(ARROW_WIDTH, ARROW_TOP_OFFSET + ARROW_HEIGHT);
        }
        bubbleArea.add(new Area(arrowPolygon));
        g2.fill(bubbleArea);
        g2.dispose();
        super.paintComponent(g);
    }
}
